#include "ota.h"
#include <ArduinoOTA.h>
#include <HTTPUpdate.h>
#include "global.h"
#include<WiFiClient.h>
#include<WiFi.h>

extern  const int   BLUE_LIGHT_PIN;

bool isSetupArduinoOTAValue = false;

void update_started() {
  Serial.println("CALLBACK:  HTTP update process started");
}

void update_finished() {
  setLocalUpgrade(false);
  Serial.println("CALLBACK:  HTTP update process finished");
}

void update_progress(int cur, int total) {
  Serial.printf("CALLBACK:  HTTP update process at %d of %d bytes...\n", cur, total);
}

void update_error(int err) {
  Serial.printf("CALLBACK:  HTTP update fatal error code %d\n", err);
}


//"http://www.smartlinked.cn/firmware/firmware.bin"
static void updateOTAInner(String url){
    //  WiFiClient client;


      WiFiClient client;

    // The line below is optional. It can be used to blink the LED on the board during flashing
    // The LED will be on during download of one buffer of data from the network. The LED will
    // be off during writing that buffer to flash
    // On a good connection the LED should flash regularly. On a bad connection the LED will be
    // on much longer than it will be off. Other pins than LED_BUILTIN may be used. The second
    // value is used to put the LED on. If the LED is on with HIGH, that value should be passed
    // httpUpdate.setLedPin(LED_BUILTIN, LOW);


    Serial.print("updateOTA");
 
    httpUpdate.onStart(update_started);
    httpUpdate.onEnd(update_finished);
    httpUpdate.onProgress(update_progress);
    httpUpdate.onError(update_error);
    httpUpdate.setLedPin(BLUE_LIGHT_PIN);

    t_httpUpdate_return ret = httpUpdate.update(client,url );
    // Or:
    //t_httpUpdate_return ret = httpUpdate.update(client, "server", 80, "/file.bin");

    switch (ret) {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }


}




bool updateOTA(){

   if(!setupArduinoOTA()){
      printStr("updateOTA ",String("ota升级未安装"));
      return false;
   }
  if(getGlobalLocalConfig()==nullptr||getGlobalLocalConfig()->getTypeConfig()==nullptr||getGlobalLocalConfig()->getTypeConfig()->getUpdateFirmware()==false){
    return false;
  }
   TypeConfig* tc =   getGlobalLocalConfig()->getTypeConfig();
  if( isStringEmpty(tc->getFirmwareUrl())){
      return false;
  }
  updateOTAInner(getGlobalLocalConfig()->getTypeConfig()->getFirmwareUrl())  ;
  return true;                                                                                                                                             
}

 

 


bool setupArduinoOTA(){
  if(!isWiFiConnected()){
    printStr("setupArduinoOTA ",String("Wifi未连接"));
    return false;
  }
    ArduinoOTA
    .onStart([]() {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH) {
        type = "sketch";
      } else {  // U_SPIFFS
        type = "filesystem";
      }

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
    })
    .onEnd([]() {
      Serial.println("\nEnd");
      getGlobalLocalConfig()->getTypeConfig()->setUpdateFirmware(false);
    })
    .onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
    })
    .onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) {
        Serial.println("Auth Failed");
      } else if (error == OTA_BEGIN_ERROR) {
        Serial.println("Begin Failed");
      } else if (error == OTA_CONNECT_ERROR) {
        Serial.println("Connect Failed");
      } else if (error == OTA_RECEIVE_ERROR) {
        Serial.println("Receive Failed");
      } else if (error == OTA_END_ERROR) {
        Serial.println("End Failed");
      }
    });

  ArduinoOTA.begin();

  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  isSetupArduinoOTAValue = true;

  printStr("setupArduinoOTA", String("OTA "));
  return true;

}

bool isSetupArduinoOTA(){
     return  isSetupArduinoOTAValue ;
}

void loopArduinoOTA(){
    if(!isSetupArduinoOTA()){

      return;
    }
    ArduinoOTA.handle();
}